#include "Syntax.h"

//静态变量
static int linenum = 0;
static bool Error = false;
static FILE * listing;
static bool isInitLL1Table=false;
static bool isInitPredict=false;
static bool isInitExps=false;
static string temp_name;

//全局变量
extern Token tokenList[1024];// token表
int INDEX = 0; // 搭配tokenList使用
Token* currentToken; // 建立语法树时使用
TreeNode* treeroot = NULL;
int LL1Table[109][109];
std::set<LexType> Predict[110];
Expression Express[110];
ExpNode ExpNodes[120];
extern void CreatLL1Table();

TreeNode * fieldDecMore();
TreeNode * varDeclaration();
TreeNode * varDecList();
TreeNode * varDec();
TreeNode * programHead();
TreeNode * declarePart();
TreeNode * programBody();
TreeNode * procDec();
TreeNode * typeDec();
TreeNode * typeDeclaration();
TreeNode * typeDecList();
TreeNode * fieldDecList();
TreeNode * procDeclaration();
TreeNode * varDecMore();
TreeNode * paramDecList();
TreeNode * param();
TreeNode * procDecPart();
TreeNode * procBody();
TreeNode * stmList();
TreeNode * stmMore();
TreeNode * stm();
TreeNode * assCall();
TreeNode * assignmentRest();
TreeNode * exp();
TreeNode * loopStm();
TreeNode * inputStm();
TreeNode * outputStm();
TreeNode * returnStm();
TreeNode * callStmRest();
TreeNode * actParamList();
TreeNode * actParamMore();
TreeNode * term();
TreeNode * simple_exp();
TreeNode * factor();
TreeNode * variable();
TreeNode * fieldvar();
TreeNode * conditionalStm();

void match (LexType tkt);
void rdErrorMessage(char * message);
void typeDef(TreeNode * t);
void varIdList(TreeNode * t);
void varIdMore(TreeNode * t);
void baseType(TreeNode * t);
void strutureType(TreeNode * t);
void arrayType(TreeNode * t);
void idMore(TreeNode * t);
void recType(TreeNode * t);
void idList(TreeNode * t);
void paramList(TreeNode * t);
void formList(TreeNode * t);
void fidMore(TreeNode * t);
void variMore(TreeNode * t);
void fieldvarMore(TreeNode * t );

bool belong(const int & n);

#define TreeNode(nkk) TreeNode(linenum,nkk)
#define defaulttoken \
    {\
        rdErrorMessage("unexpected token is here!");\
    }

void rdErrorMessage(char * message)
{
    fprintf(listing,"RD Syntax error at line %d: %s\n",currentToken->line,message);
    Error = true;
}

TreeNode * parserecur()
{
    INDEX = 0;
    listing = fopen("out.txt","w");
    TreeNode * t=NULL;
    Error = false;
    readToken();
    t = program();
    if (currentToken->wd.tok!=ENDFILE)
        rdErrorMessage("Code ends before file\n");
    if (Error)
    {
        t=NULL;
    }
    fclose(listing);
    return t;
}

void CreatLL1Table()
{
    initExps();
    InitPredict();
    if(isInitLL1Table) return ;
    isInitLL1Table=true;
    memset(LL1Table,-1,sizeof(LL1Table));
    for(int i=1; i<=105; i++)
    {
        printf("Preduct Num %d\n",i);
        for(std::set<LexType>::const_iterator it=Predict[i].begin(); it!=Predict[i].end(); ++it)
        {
            LL1Table[int(Express[i][0]->type)][int(*it)]=i;
        }
    }
}

void match(LexType tkt)
{
  if (currentToken->wd.tok == tkt) readToken();
  else
  {
      rdErrorMessage("Not Match Error ");
      fprintf(listing,"'%s'\n",currentToken->wd.str.c_str());

      printf("\nSyntax Error At Line:%d ,You Can Get The Reason In the Output File.\n",currentToken->line);
      fprintf(listing,"\nExpected: \"%s\", Instead of :\"%s\"\n",getTokenStr(tkt).c_str(),getTokenStr(currentToken->wd.tok).c_str());
      readToken();
  }
}

TreeNode * program()
{
    if(Error) return NULL;
    TreeNode * t=programHead();
    TreeNode * q=declarePart();
    TreeNode * s=programBody();

    TreeNode * root = new TreeNode(ProK);
    if(root!=NULL)
    {
        root->lineno = 0;
        if(t!=NULL) root->son[0] = t;
        else rdErrorMessage("A program head is expected!");
        if(q!=NULL) root->son[1] = q;
        if(s!=NULL) root->son[2] = s;
        else rdErrorMessage("A program body is expected!");
    }
    match(DOT);
    return root;
}

TreeNode * programHead()
{
    if(Error) return NULL;
    TreeNode * t = new TreeNode(PheadK);
    match(PROGRAM);
    if((t!=NULL)&&(currentToken->wd.tok==ID))
    {
        t->lineno = 0;
        t->name.push_back(currentToken->wd.str);
    }
    match(ID);
    return t;
}

void readToken()
{
    currentToken = &tokenList[INDEX];
    //cout << currentToken->wd.str;
    INDEX++;
}


inline bool belong(const int & n)
{
    return Predict[n].count(currentToken->wd.tok);
}

void baseType(TreeNode * t)
{
    if(Error) return;
    if(belong(15))
    {
        match(INTEGER);
        t->kind.dec = IntegerK;
    }
    else if(belong(16))
    {
        match(CHAR);
        t->kind.dec = CharK;
    }
    else defaulttoken;
}

TreeNode * fieldDecMore()
{
    if(Error) return NULL;
    TreeNode * t = NULL;
    if(belong(25)) ;
    else if(belong(26))
        t=fieldDecList();
    else defaulttoken;
    return t;
}

void varIdMore(TreeNode * t)
{
    if(Error) return;
    if(belong(37));
    else if(belong(38))
    {
        match(COMMA);
        varIdList(t);
    }
    else defaulttoken;
}

void varIdList(TreeNode * t)
{
    if(Error) return;
    if (currentToken->wd.tok==ID)
    {
        t->name.push_back(currentToken->wd.str);
        match(ID);
    }
    else
    {
        rdErrorMessage("a varid is expected here!");
        readToken();
    }
    varIdMore(t);
}

TreeNode * varDecMore()
{
    if(Error) return NULL;
    TreeNode * t =NULL;
    if(belong(34)) ;
    else if(belong(35))
        t = varDecList();
    else defaulttoken;
    return t;
}

void idMore(TreeNode * t)
{
    if(Error) return;
    if(belong(28)) ;
    else if(belong(29))
    {
        match(COMMA);
        idList(t);
    }
    else defaulttoken;
}

TreeNode * varDecList()
{
    if(Error) return NULL;
    TreeNode * t = new TreeNode(DecK);
    TreeNode * p = NULL;
    if ( t != NULL )
    {
        t->lineno = currentToken->line;
        typeDef(t);
        varIdList(t);
        match(SEMI);
        p = varDecMore();
        t->sibling = p;
    }
    return t;
}


TreeNode * varDeclaration()
{
    if(Error) return NULL;
    match(VAR);
    TreeNode * t = varDecList();
    if(t==NULL)
        rdErrorMessage("a var declaration is expected!");
    return t;
}

TreeNode * varDec()
{
    if(Error) return NULL;
    TreeNode * t = NULL;
    if(belong(30));
    else if(belong(31))
        t = varDeclaration();
    else defaulttoken;
    return t;
}

void idList(TreeNode * t)
{
    if(Error) return;
    if (currentToken->wd.tok==ID)
    {
        t->name.push_back(currentToken->wd.str);
        match(ID);
    }
    idMore(t);
}

TreeNode * procDecPart()
{
    if(Error) return NULL;
     return declarePart();
}

TreeNode * fieldDecList()
{
    if(Error) return NULL;
    TreeNode * t = new TreeNode(DecK);
    TreeNode * p = NULL;
    if (t!=NULL)
    {
        t->lineno = currentToken->line;
        if(belong(23))
        {
           baseType(t);
           idList(t);
           match(SEMI);
           p = fieldDecMore();
        }
        else if(belong(24))
        {
           arrayType(t);
           idList(t);
           match(SEMI);
           p = fieldDecMore();
        }
        else defaulttoken;
        t->sibling = p;
    }
    return t;
}

void recType(TreeNode * t)
{
    if(Error) return;
    t->kind.dec = RecordK;
    TreeNode * p = NULL;
    match(RECORD);
    p = fieldDecList();
    if(p!=NULL)
        t->son[0] = p;
    else
        rdErrorMessage("a record body is requested!");
    match(END);
}

void arrayType(TreeNode * t)
{
    if(Error) return;
     match(ARRAY);
     match(LMIDPAREN);
     if (currentToken->wd.tok== INTC)
         t->attr.ArrayAttr.low = atoi(currentToken->wd.str.c_str());
     match(INTC);
     match(UNDERANGE);
     if (currentToken->wd.tok==INTC)
         t->attr.ArrayAttr.up = atoi(currentToken->wd.str.c_str());
     match(INTC);
     match(RMIDPAREN);
     match(OF);
     baseType(t);
     t->attr.ArrayAttr.memtype = t->kind.dec;
     t->kind.dec = ArrayK;
}


void strutureType(TreeNode * t)
{
    if(Error) return;
    if(belong(17))
        arrayType(t);
    else if(belong(18))
        recType(t);
    else defaulttoken;
}

void typeDef(TreeNode * t)
{
    if(Error) return;
    if(belong(12))
        baseType(t);
    else if(belong(13))
        strutureType(t);
    else if(belong(14))
    {
        t->kind.dec = IdK;
        t->attr.type_name = currentToken->wd.str;
        match(ID);
    }
    else defaulttoken;
}

TreeNode * typeDecMore()
{
    if(Error) return NULL;
    TreeNode * t = NULL;
    if(belong(10))
        t = typeDecList();
    else if(!belong(9)) defaulttoken;
    return t;
}

TreeNode * typeDecList()
{
    if(Error) return NULL;
    TreeNode * t = new TreeNode(DecK);
    if (t != NULL)
    {
        t->lineno = currentToken->line;
        if (currentToken->wd.tok==ID)
            t->name.push_back(currentToken->wd.str);//typeId()
        match(ID);
        match(EQ);
        typeDef(t);
        match(SEMI);
        t->sibling = typeDecMore();
    }
    return t;
}

TreeNode * typeDeclaration()
{
    if(Error) return NULL;
    match(TYPE);
    TreeNode * t = typeDecList();
    if (t==NULL)
        rdErrorMessage("A type declaration is expected!");
    return t;
}

TreeNode * typeDec()
{
    if(Error) return NULL;
    TreeNode * t = NULL;
    if(belong(6))
        t = typeDeclaration();
    else if(!belong(5)) defaulttoken;
    return t;
}

TreeNode * paramMore()
{
    if(Error) return NULL;
    TreeNode * t = NULL;
    if(belong(48));
    else if(belong(49))
    {
        match(SEMI);
        t = paramDecList();
        if (t==NULL)
            rdErrorMessage("A param declaration is required!");
    }
    else defaulttoken;
    return t;
}

void fidMore(TreeNode * t)
{
    if(Error) return;
    if(belong(53));
    else if(belong(54))
    {
        match(COMMA);
        formList(t);
    }
    else defaulttoken;
}

void formList(TreeNode * t)
{
    if(Error) return;
    if (currentToken->wd.tok==ID)
    {
        t->name.push_back(currentToken->wd.str);
        match(ID);
    }
    fidMore(t);
}

TreeNode * param()
{
    if(Error) return NULL;
    TreeNode * t = new TreeNode(DecK);
    if (t!=NULL)
    {
        t->lineno = currentToken->line;

         if(belong(50))
         {
             t->attr.ProcAttr.param = ValparamType;
             typeDef(t);
             formList(t);
         }
         else if(belong(51))
         {
             match(VAR);
             t->attr.ProcAttr.param = VarparamType;
             typeDef(t);
             formList(t);
         }
         else defaulttoken;
    }
    return t;
}

TreeNode * paramDecList()
{
    if(Error) return NULL;
    TreeNode * t = param();
    TreeNode * p = paramMore();
    t->sibling = p;
    return t;
}

void paramList(TreeNode * t)
{
    if(Error) return;
    TreeNode * p = NULL;
    if(belong(45)) ;
    else if(belong(46))
    {
        p = paramDecList();
        t->son[0] = p;
    }
    else defaulttoken;
}

TreeNode * procBody()
{
    if(Error) return NULL;
    TreeNode * t = programBody();
    if (t==NULL)
        rdErrorMessage("A program body is requested!");
    return t;
}

TreeNode * procDeclaration()
{
    if(Error) return NULL;
    TreeNode * t = new TreeNode(ProcDecK);

    match(PROCEDURE);
    if (t!=NULL)
    {
        t->lineno = currentToken->line;
        if (currentToken->wd.tok==ID)
        {
            t->name.push_back(currentToken->wd.str);
            match(ID);
        }
        match(LPAREN);
        paramList(t);
        match(RPAREN);
        match(SEMI);
        t->son[1] = procDecPart();
        t->son[2] = procBody();
        t->sibling = procDec();
    }
    return t;
}

TreeNode * procDec()
{
    if(Error) return NULL;
    TreeNode * t = NULL;
    if(belong(39));
    else if(belong(40))
        t = procDeclaration();
    else defaulttoken;
    return t;
}

#define CreateDec(nkind,pointer) \
    tp = pointer##Dec();\
    TreeNode * pointer = NULL;\
    if(tp!=NULL)\
        {\
         pointer = new TreeNode(nkind);\
         pointer->son[0] = tp;\
         pointer->lineno = 0;\
        }
TreeNode * declarePart()
{
    if(Error) return NULL;
     /*类型*/
     TreeNode * tp;

     CreateDec(TypeK,type);
     /*变量*/
     CreateDec(VarK,var);
     /*函数*/
     TreeNode * proc = procDec();//CreateDec(ProcDecK,proc);

     if(var != NULL) var->sibling = proc;
     else var = proc;
     if(type != NULL) type->sibling = var;
     else type = var;
     return type;
}
#undef CreateDec(nkind,pointer)

TreeNode * stmMore()
{
    if(Error) return NULL;
    TreeNode * t = NULL;
    if(belong(59));
    else if(belong(60))
    {
        match(SEMI);
        t = stmList();
    }
    else defaulttoken;
    return t;
}

TreeNode * returnStm()
{
    if(Error) return NULL;
    TreeNode * t = new TreeNode(StmtK);//newStmtNode(ReturnK);
    t->kind.stmt = ReturnK;
    match(RETURN);
    if(t!=NULL)
        t->lineno = currentToken->line;
    return t;
}

TreeNode * conditionalStm()
{
    if(Error) return NULL;
    TreeNode * t = new TreeNode(StmtK);//newStmtNode(IfK);
    t->kind.stmt = IfK;
    match(IF);
    if(t!=NULL)
    {
        t->lineno = currentToken->line;
        t->son[0] = exp();
    }
    match(THEN);
    if(t!=NULL)  t->son[1] = stmList();
    if(currentToken->wd.tok==ELSE)
    {
        match(ELSE);
        if(t!=NULL)
            t->son[2] = stmList();
    }
    match(FI);
    return t;
}
TreeNode * loopStm()
{
    if(Error) return NULL;
    TreeNode * t = new TreeNode(StmtK);//newStmtNode(WhileK);
    t->kind.stmt = WhileK;
    match(WHILE);
    if (t!=NULL)
    {
        t->lineno = currentToken->line;
        t->son[0] = exp();
        match(DO);
        t->son[1] = stmList();
        match(ENDWH);
    }
    return t;
}

TreeNode * inputStm()
{
    if(Error) return NULL;
    TreeNode * t = new TreeNode(StmtK);//newStmtNode(ReadK);
    t->kind.stmt = ReadK;
    match(READ);
    match(LPAREN);
    if((t!=NULL)&&(currentToken->wd.tok==ID))
    {
        t->lineno = currentToken->line;
        t->name.push_back(currentToken->wd.str);
    }
    match(ID);
    match(RPAREN);
    return t;
}

TreeNode * outputStm()
{
    if(Error) return NULL;
    TreeNode * t = new TreeNode(StmtK);//newStmtNode(WriteK);
    t->kind.stmt = WriteK;
    match(WRITE);
    match(LPAREN);
    if(t!=NULL)
    {
        t->lineno = currentToken->line;
        t->son[0] = exp();
    }
    match(RPAREN);
    return t;
}

TreeNode * actParamMore()
{
    if(Error) return NULL;
    TreeNode * t = NULL;
    if(belong(79));
    else if(belong(80))
    {
        match(COMMA);
        t = actParamList();
    }
    else defaulttoken;
    return t;
}

TreeNode * actParamList()
{
    if(Error) return NULL;
    TreeNode * t = NULL;

    if(belong(77));
    else if(belong(78))
    {
        t =exp();
        if(t!=NULL)
            t->sibling = actParamMore();
    }
    else defaulttoken;
    return t;
}

TreeNode * callStmRest()
{
    if(Error) return NULL;
    TreeNode * t=new TreeNode(StmtK);//newStmtNode(CallK);
    t->kind.stmt = CallK;
    match(LPAREN);
    /*函数调用时，其子节点指向实参*/
    if(t!=NULL)
    {
        t->lineno = currentToken->line;
        /*函数名的结点也用表达式类型结点*/
        TreeNode * son0 = new TreeNode(ExpK);//newExpNode(VariK);
        son0->kind.exp = VariK;
        if(son0!=NULL)
        {
            son0->lineno = currentToken->line;
            son0->name.push_back(temp_name);
            t->son[0] = son0;
        }
        t->son[1] = actParamList();
    }
    match(RPAREN);
    return t;
}

void fieldvarMore(TreeNode * t )
{
    if(Error) return;
    if(belong(97)) ;
    else if(belong(98))//case LMIDPAREN:
    {
        match(LMIDPAREN);
        /*用来以后求出其表达式的值，送入用于数组下标计算*/
        t->son[0] = exp();
        t->son[0]->attr.ExpAttr.varkind = ArrayMembV;
        match(RMIDPAREN);
    }
    else defaulttoken;
}

TreeNode * fieldvar()
{
    if(Error) return NULL;
    /*注意，可否将此处的IdEK改为一个新的标识，用来记录记录类型的域*/
    TreeNode * t = new TreeNode(ExpK);//newExpNode(VariK);
    t->kind.exp = VariK;
    if ((t!=NULL) && (currentToken->wd.tok==ID))
      {
          t->lineno = currentToken->line;
          t->name.push_back(currentToken->wd.str);
      }
    match(ID);
    fieldvarMore(t);
    return t;
}

void variMore(TreeNode * t)
{
    if(Error) return;
    if(belong(93));
    else if(belong(94))
    {
        match(LMIDPAREN);
        /*用来以后求出其表达式的值，送入用于数组下标计算*/
        t->son[0] = exp();
        t->attr.ExpAttr.varkind = ArrayMembV;
        /*此表达式为数组成员变量类型*/
        t->son[0]->attr.ExpAttr.varkind = IdV;
        match(RMIDPAREN);
    }
    else if(belong(95))
    {
        match(DOT);
        /*第一个儿子指向域成员变量结点*/
        t->son[0] = fieldvar();
        t->attr.ExpAttr.varkind = FieldMembV;
        t->son[0]->attr.ExpAttr.varkind = IdV;
    }
    else defaulttoken;
}

TreeNode * variable()
{
    if(Error) return NULL;
    TreeNode * t = new TreeNode(ExpK);//newExpNode(VariK);
    t->kind.exp = VariK;
    if ((t!=NULL) && (currentToken->wd.tok==ID))
    {
        t->lineno = currentToken->line;
        t->name.push_back(currentToken->wd.str);
    }
    match(ID);
    variMore(t);
    return t;
}

TreeNode * factor()
{
    if(Error) return NULL;
    TreeNode * t = NULL;
    if(belong(90))
    {
        t = new TreeNode(ExpK);//newExpNode(ConstK);
        t->kind.exp = ConstK;

        if ((t!=NULL) && (currentToken->wd.tok==INTC))
        {
          t->lineno = currentToken->line;
          t->attr.ExpAttr.val = atoi(currentToken->wd.str.c_str());
        }
        /* 当前单词token与数字单词NUM匹配 */
        match(INTC);
    }
    else if(belong(91))
        t = variable();
    else if(belong(89))
    {
        match(LPAREN);
        t = exp();
        match(RPAREN);
    }
    else defaulttoken;
    return t;
}
TreeNode * term()
{
    if(Error) return NULL;
    TreeNode * t = factor();
    while ((currentToken->wd.tok==TIMES)||(currentToken->wd.tok==OVER))
    {
        TreeNode * p = new TreeNode(ExpK);//newExpNode(OpK);
        p->kind.exp = OpK;
        if (p!=NULL)
        {
          p->lineno= currentToken->line;
          p->son[0] = t;
          p->attr.ExpAttr.op = currentToken->wd.tok;
          t = p;
        }
        match(currentToken->wd.tok);
        p->son[1] = factor();
    }
    return t;
}

TreeNode * simple_exp()
{
    if(Error) return NULL;
    TreeNode * t = term();
    while ((currentToken->wd.tok==PLUS)||(currentToken->wd.tok==MINUS))
    {
        TreeNode * p = new TreeNode(ExpK);//newExpNode(OpK);
        p->kind.exp = OpK;
        if (p!=NULL)
        {
          p->lineno = currentToken->line;
          p->son[0] = t;
          p->attr.ExpAttr.op = currentToken->wd.tok;
          t = p;
          match(currentToken->wd.tok);
          t->son[1] = term();
        }
    }
  return t;
}

TreeNode * exp()
{
    if(Error) return NULL;
    TreeNode * t = simple_exp();
    if ((currentToken->wd.tok==LT)||(currentToken->wd.tok==EQ))
    {
        TreeNode * p = new TreeNode(ExpK);
        p->kind.exp = OpK;
        if (p!=NULL)
        {
            p->lineno = currentToken->line;
            p->son[0] = t;
            p->attr.ExpAttr.op = currentToken->wd.tok;
            t = p;
        }
        match(currentToken->wd.tok);
          t->son[1] = simple_exp();
    }
    return t;
}

TreeNode * assignmentRest()
{
    if(Error) return NULL;
    TreeNode * t = new TreeNode(StmtK);
    t->kind.stmt = AssignK;
    if(t!=NULL)
    {
        t->lineno = currentToken->line;
        /*处理第一个儿子结点，为变量表达式类型节点*/
        TreeNode * son1 = new TreeNode(ExpK);//newExpNode(VariK);
        son1->kind.exp = VariK;
        if(son1!=NULL)
        {
            son1->lineno = currentToken->line;
            son1->name.push_back(temp_name);
            variMore(son1);
            t->son[0] = son1;
        }
        /*赋值号匹配*/
        match(ASSIGN);
        /*处理第二个儿子节点*/
        t->son[1] = exp();
    }
    return t;
}

TreeNode * assCall()
{
    if(Error) return NULL;
    TreeNode * t = NULL;
    if(belong(67))
        t = assignmentRest();
    else if(belong(68))
        t = callStmRest();
    else defaulttoken;
    return t;
}

TreeNode * stm()
{
    if(Error) return NULL;
    TreeNode * t = NULL;
    if(belong(61))
        t = conditionalStm();
    else if(belong(62))
        t = loopStm();
    else if(belong(63))
        t = inputStm();
    else if(belong(64))
        t = outputStm();
    else if(belong(65))
        t = returnStm();
    else if(belong(66))
    {
        temp_name = currentToken->wd.str;
        match(ID);
        t = assCall();
    }
    else defaulttoken;
    return t;
}

TreeNode * stmList()
{
    if(Error) return NULL;
    TreeNode * t = stm();
    if(t!=NULL)
        t->sibling = stmMore();
    return t;
}

TreeNode * programBody()
{
    if(Error) return NULL;
    TreeNode * t = new TreeNode(StmLK);//newStmlNode();
    match(BEGIN);
    if(t!=NULL)
    {
        t->lineno = 0;
        t->son[0] = stmList();
    }
    match(END);
    return t;
}

void InitPredict()
{
    if(isInitPredict) return ;
    isInitPredict=true;
    Predict[1].insert(LexType::PROGRAM);
    Predict[2].insert(LexType::PROGRAM);
    Predict[3].insert(LexType::ID);
    Predict[4].insert(LexType::TYPE);
    Predict[4].insert(LexType::VAR);
    Predict[4].insert(LexType::PROCEDURE);
    Predict[4].insert(LexType::BEGIN);
    Predict[5].insert(LexType::VAR);
    Predict[5].insert(LexType::PROCEDURE);
    Predict[5].insert(LexType::BEGIN);
    Predict[6].insert(LexType::TYPE);
    Predict[7].insert(LexType::TYPE);
    Predict[8].insert(LexType::ID);
    Predict[9].insert(LexType::VAR);
    Predict[9].insert(LexType::PROCEDURE);
    Predict[9].insert(LexType::BEGIN);
    Predict[10].insert(LexType::ID);
    Predict[11].insert(LexType::ID);
    Predict[12].insert(LexType::INTEGER);
    Predict[12].insert(LexType::CHAR);
    Predict[13].insert(LexType::ARRAY);
    Predict[13].insert(LexType::RECORD);
    Predict[14].insert(LexType::ID);
    Predict[15].insert(LexType::INTEGER);
    Predict[16].insert(LexType::CHAR);
    Predict[17].insert(LexType::ARRAY);
    Predict[18].insert(LexType::RECORD);
    Predict[19].insert(LexType::ARRAY);
#ifndef NoCharC
    Predict[20].insert(LexType::CHARC);
#endif
    Predict[20].insert(LexType::INTC);
#ifndef NoCharC
    Predict[21].insert(LexType::CHARC);
#endif
    Predict[21].insert(LexType::INTC);
    Predict[22].insert(LexType::RECORD);
    Predict[23].insert(LexType::INTEGER);
    Predict[23].insert(LexType::CHAR);
    Predict[24].insert(LexType::ARRAY);
    Predict[25].insert(LexType::END);
    Predict[26].insert(LexType::INTEGER);
    Predict[26].insert(LexType::CHAR);
    Predict[26].insert(LexType::ARRAY);
    Predict[27].insert(LexType::ID);
    Predict[28].insert(LexType::SEMI);
    Predict[29].insert(LexType::COMMA);
    Predict[30].insert(LexType::PROCEDURE);
    Predict[30].insert(LexType::BEGIN);
    Predict[31].insert(LexType::VAR);
    Predict[32].insert(LexType::VAR);
    Predict[33].insert(LexType::INTEGER);
    Predict[33].insert(LexType::CHAR);
    Predict[33].insert(LexType::ARRAY);
    Predict[33].insert(LexType::RECORD);
    Predict[33].insert(LexType::ID);
    Predict[34].insert(LexType::PROCEDURE);
    Predict[34].insert(LexType::BEGIN);
    Predict[35].insert(LexType::INTEGER);
    Predict[35].insert(LexType::CHAR);
    Predict[35].insert(LexType::ARRAY);
    Predict[35].insert(LexType::RECORD);
    Predict[35].insert(LexType::ID);
    Predict[36].insert(LexType::ID);
    Predict[37].insert(LexType::SEMI);
    Predict[38].insert(LexType::COMMA);
    Predict[39].insert(LexType::BEGIN);
    Predict[40].insert(LexType::PROCEDURE);
    Predict[41].insert(LexType::PROCEDURE);
    Predict[42].insert(LexType::BEGIN);
    Predict[43].insert(LexType::PROCEDURE);
    Predict[44].insert(LexType::ID);
    Predict[45].insert(LexType::RPAREN);
    Predict[46].insert(LexType::INTEGER);
    Predict[46].insert(LexType::CHAR);
    Predict[46].insert(LexType::ARRAY);
    Predict[46].insert(LexType::RECORD);
    Predict[46].insert(LexType::ID);
    Predict[46].insert(LexType::VAR);
    Predict[47].insert(LexType::INTEGER);
    Predict[47].insert(LexType::CHAR);
    Predict[47].insert(LexType::ARRAY);
    Predict[47].insert(LexType::RECORD);
    Predict[47].insert(LexType::ID);
    Predict[47].insert(LexType::VAR);
    Predict[48].insert(LexType::RPAREN);
    Predict[49].insert(LexType::SEMI);
    Predict[50].insert(LexType::INTEGER);
    Predict[50].insert(LexType::CHAR);
    Predict[50].insert(LexType::ARRAY);
    Predict[50].insert(LexType::RECORD);
    Predict[50].insert(LexType::ID);
    Predict[51].insert(LexType::VAR);
    Predict[52].insert(LexType::ID);
    Predict[53].insert(LexType::SEMI);
    Predict[53].insert(LexType::RPAREN);
    Predict[54].insert(LexType::COMMA);
    Predict[55].insert(LexType::TYPE);
    Predict[55].insert(LexType::VAR);
    Predict[55].insert(LexType::PROCEDURE);
    Predict[55].insert(LexType::BEGIN);
    Predict[56].insert(LexType::BEGIN);
    Predict[57].insert(LexType::BEGIN);
    Predict[58].insert(LexType::ID);
    Predict[58].insert(LexType::IF);
    Predict[58].insert(LexType::WHILE);
    Predict[58].insert(LexType::RETURN);
    Predict[58].insert(LexType::READ);
    Predict[58].insert(LexType::WRITE);
    Predict[59].insert(LexType::END);
    Predict[59].insert(LexType::ENDWH);
    Predict[59].insert(LexType::ELSE);
    Predict[59].insert(LexType::FI);
    Predict[60].insert(LexType::SEMI);
    Predict[61].insert(LexType::IF);
    Predict[62].insert(LexType::WHILE);
    Predict[63].insert(LexType::READ);
    Predict[64].insert(LexType::WRITE);
    Predict[65].insert(LexType::RETURN);
    Predict[66].insert(LexType::ID);
    Predict[67].insert(LexType::ASSIGN);
    Predict[67].insert(LexType::LMIDPAREN);
    Predict[67].insert(LexType::DOT);
    Predict[68].insert(LexType::LPAREN);
    Predict[69].insert(LexType::ASSIGN);
    Predict[69].insert(LexType::LMIDPAREN);
    Predict[69].insert(LexType::DOT);
    Predict[70].insert(LexType::IF);
    Predict[71].insert(LexType::WHILE);
    Predict[72].insert(LexType::READ);
    Predict[73].insert(LexType::ID);
    Predict[74].insert(LexType::WRITE);
    Predict[75].insert(LexType::RETURN);
    Predict[76].insert(LexType::LPAREN);
    Predict[77].insert(LexType::RPAREN);
    Predict[78].insert(LexType::ID);
#ifndef NoCharC
    Predict[78].insert(LexType::CHARC);
#endif
    Predict[78].insert(LexType::INTC);
    Predict[78].insert(LexType::LPAREN);
    Predict[79].insert(LexType::RPAREN);
    Predict[80].insert(LexType::COMMA);
    Predict[81].insert(LexType::LPAREN);
#ifndef NoCharC
    Predict[81].insert(LexType::CHARC);
#endif
    Predict[81].insert(LexType::INTC);
    Predict[81].insert(LexType::ID);
    Predict[82].insert(LexType::LT);
    Predict[82].insert(LexType::EQ);
    Predict[83].insert(LexType::LPAREN);
#ifndef NoCharC
    Predict[83].insert(LexType::CHARC);
#endif
    Predict[83].insert(LexType::INTC);
    Predict[83].insert(LexType::ID);
    Predict[84].insert(LexType::LT);
    Predict[84].insert(LexType::EQ);
    Predict[84].insert(LexType::THEN);
    Predict[84].insert(LexType::DO);
    Predict[84].insert(LexType::RPAREN);
    Predict[84].insert(LexType::END);
    Predict[84].insert(LexType::SEMI);
    Predict[84].insert(LexType::COMMA);
    Predict[84].insert(LexType::ENDWH);
    Predict[84].insert(LexType::ELSE);
    Predict[84].insert(LexType::FI);
    Predict[84].insert(LexType::RMIDPAREN);
    Predict[85].insert(LexType::PLUS);
    Predict[85].insert(LexType::MINUS);
    Predict[86].insert(LexType::LPAREN);
#ifndef NoCharC
    Predict[86].insert(LexType::CHARC);
#endif
    Predict[86].insert(LexType::INTC);
    Predict[86].insert(LexType::ID);
    Predict[87].insert(LexType::PLUS);
    Predict[87].insert(LexType::MINUS);
    Predict[87].insert(LexType::LT);
    Predict[87].insert(LexType::EQ);
    Predict[87].insert(LexType::THEN);
    Predict[87].insert(LexType::ELSE);
    Predict[87].insert(LexType::FI);
    Predict[87].insert(LexType::DO);
    Predict[87].insert(LexType::ENDWH);
    Predict[87].insert(LexType::RPAREN);
    Predict[87].insert(LexType::END);
    Predict[87].insert(LexType::SEMI);
    Predict[87].insert(LexType::COMMA);
    Predict[87].insert(LexType::RMIDPAREN);
    Predict[88].insert(LexType::TIMES);
    Predict[88].insert(LexType::OVER);
    Predict[89].insert(LexType::LPAREN);
#ifndef NoCharC
    Predict[90].insert(LexType::CHARC);
#endif
    Predict[90].insert(LexType::INTC);
    Predict[91].insert(LexType::ID);
    Predict[92].insert(LexType::ID);
    Predict[93].insert(LexType::ASSIGN);
    Predict[93].insert(LexType::TIMES);
    Predict[93].insert(LexType::OVER);
    Predict[93].insert(LexType::PLUS);
    Predict[93].insert(LexType::MINUS);
    Predict[93].insert(LexType::LT);
    Predict[93].insert(LexType::EQ);
    Predict[93].insert(LexType::THEN);
    Predict[93].insert(LexType::ELSE);
    Predict[93].insert(LexType::FI);
    Predict[93].insert(LexType::DO);
    Predict[93].insert(LexType::ENDWH);
    Predict[93].insert(LexType::RPAREN);
    Predict[93].insert(LexType::END);
    Predict[93].insert(LexType::SEMI);
    Predict[93].insert(LexType::COMMA);
    Predict[93].insert(LexType::RMIDPAREN);
    Predict[94].insert(LexType::LMIDPAREN);
    Predict[95].insert(LexType::DOT);
    Predict[96].insert(LexType::ID);
    Predict[97].insert(LexType::ASSIGN);
    Predict[97].insert(LexType::TIMES);
    Predict[97].insert(LexType::OVER);
    Predict[97].insert(LexType::PLUS);
    Predict[97].insert(LexType::MINUS);
    Predict[97].insert(LexType::LT);
    Predict[97].insert(LexType::EQ);
    Predict[97].insert(LexType::THEN);
    Predict[97].insert(LexType::ELSE);
    Predict[97].insert(LexType::FI);
    Predict[97].insert(LexType::DO);
    Predict[97].insert(LexType::ENDWH);
    Predict[97].insert(LexType::RPAREN);
    Predict[97].insert(LexType::END);
    Predict[97].insert(LexType::SEMI);
    Predict[97].insert(LexType::COMMA);
    Predict[98].insert(LexType::LMIDPAREN);
    Predict[99].insert(LexType::LT);
    Predict[100].insert(LexType::EQ);
    Predict[101].insert(LexType::PLUS);
    Predict[102].insert(LexType::MINUS);
    Predict[103].insert(LexType::TIMES);
    Predict[104].insert(LexType::OVER);
#ifndef NoCharC
    Predict[105].insert(LexType::CHARC);
#endif
}

void initExps()
{
    if(isInitExps) return ;
    isInitExps = true;

    for (int var = 0; var <= LexType::UNDERANGE; ++var)
    {
        ExpNodes[var].NTflag = ISTERMINAL;
        ExpNodes[var].type = var;
    }
    for(int i = int(LexType::UNDERANGE)+1 ; i <= int(LexType::UNDERANGE)+int(NonTerminal::MultOp)+1; i++)
    {
        ExpNodes[i].NTflag = NOTERMINAL;
        ExpNodes[i].type = i - LexType::UNDERANGE - 1;
    }

    Express[1].push_back(searchForNode(NonTerminal::Program, NOTERMINAL));
    Express[1].push_back(searchForNode(ProgramHead,NOTERMINAL));
    Express[1].push_back(searchForNode(DeclarePart,NOTERMINAL));
    Express[1].push_back(searchForNode(ProgramBody,NOTERMINAL));
    Express[2].push_back(searchForNode(ProgramHead,NOTERMINAL));
    Express[2].push_back(searchForNode(PROGRAM,ISTERMINAL));
    Express[2].push_back(searchForNode(ProgramName,NOTERMINAL));
    Express[3].push_back(searchForNode(ProgramName,NOTERMINAL));
    Express[3].push_back(searchForNode(ID,ISTERMINAL));
    Express[4].push_back(searchForNode(DeclarePart,NOTERMINAL));
    Express[4].push_back(searchForNode(TypeDec,NOTERMINAL));
    Express[4].push_back(searchForNode(VarDec,NOTERMINAL));
    Express[4].push_back(searchForNode(ProcDec,NOTERMINAL));
    Express[5].push_back(searchForNode(TypeDec,NOTERMINAL));
    Express[5].push_back(searchForNode(LAMBDA,ISTERMINAL));
    Express[6].push_back(searchForNode(TypeDec,NOTERMINAL));
    Express[6].push_back(searchForNode(TypeDeclaration,NOTERMINAL));
    Express[7].push_back(searchForNode(TypeDec,NOTERMINAL));
    Express[7].push_back(searchForNode(TYPE,ISTERMINAL));
    Express[7].push_back(searchForNode(TypeDecList,NOTERMINAL));
    Express[8].push_back(searchForNode(TypeDecList,NOTERMINAL));
    Express[8].push_back(searchForNode(TypeId,NOTERMINAL));
    Express[8].push_back(searchForNode(EQ,ISTERMINAL));/****/
    Express[8].push_back(searchForNode(TypeName,NOTERMINAL));
    Express[8].push_back(searchForNode(SEMI,ISTERMINAL));
    Express[8].push_back(searchForNode(TypeDecMore,NOTERMINAL));
    Express[9].push_back(searchForNode(TypeDecMore,NOTERMINAL));
    Express[9].push_back(searchForNode(LAMBDA,ISTERMINAL));
    Express[10].push_back(searchForNode(TypeDecMore,NOTERMINAL));
    Express[10].push_back(searchForNode(TypeDecList,NOTERMINAL));
    Express[11].push_back(searchForNode(TypeId,NOTERMINAL));
    Express[11].push_back(searchForNode(ID,ISTERMINAL));
    Express[12].push_back(searchForNode(TypeName,NOTERMINAL));
    Express[12].push_back(searchForNode(BaseType,NOTERMINAL));
    Express[13].push_back(searchForNode(TypeName,NOTERMINAL));
    Express[13].push_back(searchForNode(StructureType,NOTERMINAL));
    Express[14].push_back(searchForNode(TypeName,NOTERMINAL));
    Express[14].push_back(searchForNode(ID,ISTERMINAL));
    Express[15].push_back(searchForNode(BaseType,NOTERMINAL));
    Express[15].push_back(searchForNode(INTEGER,ISTERMINAL));
    Express[16].push_back(searchForNode(BaseType,NOTERMINAL));
    Express[16].push_back(searchForNode(CHAR,ISTERMINAL));
    Express[17].push_back(searchForNode(StructureType,NOTERMINAL));
    Express[17].push_back(searchForNode(ArrayType,NOTERMINAL));
    Express[18].push_back(searchForNode(StructureType,NOTERMINAL));
    Express[18].push_back(searchForNode(RecType,NOTERMINAL));
    Express[19].push_back(searchForNode(ArrayType,NOTERMINAL));
    Express[19].push_back(searchForNode(ARRAY,ISTERMINAL));
    Express[19].push_back(searchForNode(LMIDPAREN,ISTERMINAL));
    Express[19].push_back(searchForNode(Low,NOTERMINAL));
    Express[19].push_back(searchForNode(UNDERANGE,ISTERMINAL));
    Express[19].push_back(searchForNode(Top,NOTERMINAL));
    Express[19].push_back(searchForNode(RMIDPAREN,ISTERMINAL));
    Express[19].push_back(searchForNode(OF,ISTERMINAL));
    Express[19].push_back(searchForNode(BaseType,NOTERMINAL));
    Express[20].push_back(searchForNode(Low,NOTERMINAL));
    Express[20].push_back(searchForNode(INTC,ISTERMINAL));
    Express[21].push_back(searchForNode(Top,NOTERMINAL));
    Express[21].push_back(searchForNode(INTC,ISTERMINAL));
    Express[22].push_back(searchForNode(RecType,NOTERMINAL));
    Express[22].push_back(searchForNode(RECORD,ISTERMINAL));
    Express[22].push_back(searchForNode(FieldDecList,NOTERMINAL));
    Express[22].push_back(searchForNode(END,ISTERMINAL));
    Express[23].push_back(searchForNode(FieldDecList,NOTERMINAL));
    Express[23].push_back(searchForNode(BaseType,NOTERMINAL));
    Express[23].push_back(searchForNode(IdList,NOTERMINAL));
    Express[23].push_back(searchForNode(SEMI,ISTERMINAL));
    Express[23].push_back(searchForNode(FieldDecMore,NOTERMINAL));
    Express[24].push_back(searchForNode(FieldDecList,NOTERMINAL));
    Express[24].push_back(searchForNode(ArrayType,NOTERMINAL));
    Express[24].push_back(searchForNode(IdList,NOTERMINAL));
    Express[24].push_back(searchForNode(SEMI,ISTERMINAL));
    Express[24].push_back(searchForNode(FieldDecMore,NOTERMINAL));
    Express[25].push_back(searchForNode(FieldDecMore,NOTERMINAL));
    Express[25].push_back(searchForNode(LAMBDA,ISTERMINAL));
    Express[26].push_back(searchForNode(FieldDecMore,NOTERMINAL));
    Express[26].push_back(searchForNode(FieldDecList,NOTERMINAL));
    Express[27].push_back(searchForNode(IdList,NOTERMINAL));
    Express[27].push_back(searchForNode(ID,ISTERMINAL));
    Express[27].push_back(searchForNode(IdMore,NOTERMINAL));
    Express[28].push_back(searchForNode(IdMore,NOTERMINAL));
    Express[28].push_back(searchForNode(LAMBDA,ISTERMINAL));
    Express[29].push_back(searchForNode(IdMore,NOTERMINAL));
    Express[29].push_back(searchForNode(COMMA,ISTERMINAL));
    Express[29].push_back(searchForNode(IdList,NOTERMINAL));
    Express[30].push_back(searchForNode(VarDec,NOTERMINAL));
    Express[30].push_back(searchForNode(LAMBDA,ISTERMINAL));
    Express[31].push_back(searchForNode(VarDec,NOTERMINAL));
    Express[31].push_back(searchForNode(VarDeclaration,NOTERMINAL));
    Express[32].push_back(searchForNode(VarDeclaration,NOTERMINAL));
    Express[32].push_back(searchForNode(VAR,ISTERMINAL));
    Express[32].push_back(searchForNode(VarDecList,NOTERMINAL));
    Express[33].push_back(searchForNode(VarDecList,NOTERMINAL));
    Express[33].push_back(searchForNode(TypeName,NOTERMINAL));
    Express[33].push_back(searchForNode(VarIdList,NOTERMINAL));
    Express[33].push_back(searchForNode(SEMI,ISTERMINAL));
    Express[33].push_back(searchForNode(VarDecMore,NOTERMINAL));
    Express[34].push_back(searchForNode(VarDecMore,NOTERMINAL));
    Express[34].push_back(searchForNode(LAMBDA,ISTERMINAL));
    Express[35].push_back(searchForNode(VarDecMore,NOTERMINAL));
    Express[35].push_back(searchForNode(VarDecList,NOTERMINAL));
    Express[36].push_back(searchForNode(VarIdList,NOTERMINAL));
    Express[36].push_back(searchForNode(ID,ISTERMINAL));
    Express[36].push_back(searchForNode(VarIdMore,NOTERMINAL));
    Express[37].push_back(searchForNode(VarIdMore,NOTERMINAL));
    Express[37].push_back(searchForNode(LAMBDA,ISTERMINAL));
    Express[38].push_back(searchForNode(VarIdMore,NOTERMINAL));
    Express[38].push_back(searchForNode(COMMA,ISTERMINAL));
    Express[38].push_back(searchForNode(VarIdList,NOTERMINAL));
    Express[39].push_back(searchForNode(ProcDec,NOTERMINAL));
    Express[39].push_back(searchForNode(LAMBDA,ISTERMINAL));
    Express[40].push_back(searchForNode(ProcDec,NOTERMINAL));
    Express[40].push_back(searchForNode(ProcDeclaration,NOTERMINAL));
    Express[41].push_back(searchForNode(ProcDeclaration,NOTERMINAL));
    Express[41].push_back(searchForNode(PROCEDURE,ISTERMINAL));
    Express[41].push_back(searchForNode(ProcName,NOTERMINAL));
    Express[41].push_back(searchForNode(LPAREN,ISTERMINAL));
    Express[41].push_back(searchForNode(ParamList,NOTERMINAL));
    Express[41].push_back(searchForNode(RPAREN,ISTERMINAL));
    Express[41].push_back(searchForNode(SEMI,ISTERMINAL));
    Express[41].push_back(searchForNode(ProcDecPart,NOTERMINAL));
    Express[41].push_back(searchForNode(ProcBody,NOTERMINAL));
    Express[41].push_back(searchForNode(ProcDecMore,NOTERMINAL));
    Express[42].push_back(searchForNode(ProcDecMore,NOTERMINAL));
    Express[42].push_back(searchForNode(LAMBDA,ISTERMINAL));
    Express[43].push_back(searchForNode(ProcDecMore,NOTERMINAL));
    Express[43].push_back(searchForNode(ProcDeclaration,NOTERMINAL));
    Express[44].push_back(searchForNode(ProcName,NOTERMINAL));
    Express[44].push_back(searchForNode(ID,ISTERMINAL));
    Express[45].push_back(searchForNode(ParamList,NOTERMINAL));
    Express[45].push_back(searchForNode(LAMBDA,ISTERMINAL));
    Express[46].push_back(searchForNode(ParamList,NOTERMINAL));
    Express[46].push_back(searchForNode(ParamDecList,NOTERMINAL));
    Express[47].push_back(searchForNode(ParamDecList,NOTERMINAL));
    Express[47].push_back(searchForNode(Param,NOTERMINAL));
    Express[47].push_back(searchForNode(ParamMore,NOTERMINAL));
    Express[48].push_back(searchForNode(ParamMore,NOTERMINAL));
    Express[48].push_back(searchForNode(LAMBDA,ISTERMINAL));
    Express[49].push_back(searchForNode(ParamMore,NOTERMINAL));
    Express[49].push_back(searchForNode(SEMI,ISTERMINAL));
    Express[49].push_back(searchForNode(ParamDecList,NOTERMINAL));
    Express[50].push_back(searchForNode(Param,NOTERMINAL));
    Express[50].push_back(searchForNode(TypeName,NOTERMINAL));
    Express[50].push_back(searchForNode(FormList,NOTERMINAL));
    Express[51].push_back(searchForNode(Param,NOTERMINAL));
    Express[51].push_back(searchForNode(VAR,ISTERMINAL));
    Express[51].push_back(searchForNode(TypeName,NOTERMINAL));
    Express[51].push_back(searchForNode(FormList,NOTERMINAL));
    Express[52].push_back(searchForNode(FormList,NOTERMINAL));
    Express[52].push_back(searchForNode(ID,ISTERMINAL));
    Express[52].push_back(searchForNode(FidMore,NOTERMINAL));
    Express[53].push_back(searchForNode(FidMore,NOTERMINAL));
    Express[53].push_back(searchForNode(LAMBDA,ISTERMINAL));
    Express[54].push_back(searchForNode(FidMore,NOTERMINAL));
    Express[54].push_back(searchForNode(COMMA,ISTERMINAL));
    Express[54].push_back(searchForNode(FormList,NOTERMINAL));
    Express[55].push_back(searchForNode(ProcDecPart,NOTERMINAL));
    Express[55].push_back(searchForNode(DeclarePart,NOTERMINAL));
    Express[56].push_back(searchForNode(ProcBody,NOTERMINAL));
    Express[56].push_back(searchForNode(ProgramBody,NOTERMINAL));
    Express[57].push_back(searchForNode(ProgramBody,NOTERMINAL));
    Express[57].push_back(searchForNode(BEGIN,ISTERMINAL));
    Express[57].push_back(searchForNode(StmList,NOTERMINAL));
    Express[57].push_back(searchForNode(END,ISTERMINAL));
    Express[58].push_back(searchForNode(StmList,NOTERMINAL));
    Express[58].push_back(searchForNode(Stm,NOTERMINAL));
    Express[58].push_back(searchForNode(StmMore,NOTERMINAL));
    Express[59].push_back(searchForNode(StmMore,NOTERMINAL));
    Express[59].push_back(searchForNode(LAMBDA,ISTERMINAL));
    Express[60].push_back(searchForNode(StmMore,NOTERMINAL));
    Express[60].push_back(searchForNode(SEMI,ISTERMINAL));
    Express[60].push_back(searchForNode(StmList,NOTERMINAL));
    Express[61].push_back(searchForNode(Stm,NOTERMINAL));
    Express[61].push_back(searchForNode(ConditionalStm,NOTERMINAL));
    Express[62].push_back(searchForNode(Stm,NOTERMINAL));
    Express[62].push_back(searchForNode(LoopStm,NOTERMINAL));
    Express[63].push_back(searchForNode(Stm,NOTERMINAL));
    Express[63].push_back(searchForNode(InputStm,NOTERMINAL));
    Express[64].push_back(searchForNode(Stm,NOTERMINAL));
    Express[64].push_back(searchForNode(OutputStm,NOTERMINAL));
    Express[65].push_back(searchForNode(Stm,NOTERMINAL));
    Express[65].push_back(searchForNode(ReturnStm,NOTERMINAL));
    Express[66].push_back(searchForNode(Stm,NOTERMINAL));
    Express[66].push_back(searchForNode(ID,ISTERMINAL));
    Express[66].push_back(searchForNode(AssCall,NOTERMINAL));
    Express[67].push_back(searchForNode(AssCall,NOTERMINAL));
    Express[67].push_back(searchForNode(AssignmentRest,NOTERMINAL));
    Express[68].push_back(searchForNode(AssCall,NOTERMINAL));
    Express[68].push_back(searchForNode(CallStmRest,NOTERMINAL));
    Express[69].push_back(searchForNode(AssignmentRest,NOTERMINAL));
    Express[69].push_back(searchForNode(VariMore,NOTERMINAL));
    Express[69].push_back(searchForNode(ASSIGN,ISTERMINAL));
    Express[69].push_back(searchForNode(Exp,NOTERMINAL));
    Express[70].push_back(searchForNode(ConditionalStm,NOTERMINAL));
    Express[70].push_back(searchForNode(IF,ISTERMINAL));
    Express[70].push_back(searchForNode(RelExp,NOTERMINAL));
    Express[70].push_back(searchForNode(THEN,ISTERMINAL));
    Express[70].push_back(searchForNode(StmList,NOTERMINAL));
    Express[70].push_back(searchForNode(ELSE,ISTERMINAL));
    Express[70].push_back(searchForNode(StmList,NOTERMINAL));
    Express[70].push_back(searchForNode(FI,ISTERMINAL));
    Express[71].push_back(searchForNode(LoopStm,NOTERMINAL));
    Express[71].push_back(searchForNode(WHILE,ISTERMINAL));
    Express[71].push_back(searchForNode(RelExp,NOTERMINAL));
    Express[71].push_back(searchForNode(DO,ISTERMINAL));
    Express[71].push_back(searchForNode(StmList,NOTERMINAL));
    Express[71].push_back(searchForNode(ENDWH,ISTERMINAL));
    Express[72].push_back(searchForNode(InputStm,NOTERMINAL));
    Express[72].push_back(searchForNode(READ,ISTERMINAL));
    Express[72].push_back(searchForNode(LPAREN,ISTERMINAL));
    Express[72].push_back(searchForNode(InVar,NOTERMINAL));
    Express[72].push_back(searchForNode(RPAREN,ISTERMINAL));
    Express[73].push_back(searchForNode(InVar,NOTERMINAL));
    Express[73].push_back(searchForNode(ID,ISTERMINAL));
    Express[74].push_back(searchForNode(OutputStm,NOTERMINAL));
    Express[74].push_back(searchForNode(WRITE,ISTERMINAL));
    Express[74].push_back(searchForNode(LPAREN,ISTERMINAL));
    Express[74].push_back(searchForNode(Exp,NOTERMINAL));
    Express[74].push_back(searchForNode(RPAREN,ISTERMINAL));
    Express[75].push_back(searchForNode(ReturnStm,NOTERMINAL));
    Express[75].push_back(searchForNode(RETURN,ISTERMINAL));
    Express[76].push_back(searchForNode(CallStmRest,NOTERMINAL));
    Express[76].push_back(searchForNode(LPAREN,ISTERMINAL));
    Express[76].push_back(searchForNode(ActParamList,NOTERMINAL));
    Express[76].push_back(searchForNode(RPAREN,ISTERMINAL));
    Express[77].push_back(searchForNode(ActParamList,NOTERMINAL));
    Express[77].push_back(searchForNode(LAMBDA,ISTERMINAL));
    Express[78].push_back(searchForNode(ActParamList,NOTERMINAL));
    Express[78].push_back(searchForNode(Exp,NOTERMINAL));
    Express[78].push_back(searchForNode(ActParamMore,NOTERMINAL));
    Express[79].push_back(searchForNode(ActParamMore,NOTERMINAL));
    Express[79].push_back(searchForNode(LAMBDA,ISTERMINAL));
    Express[80].push_back(searchForNode(ActParamMore,NOTERMINAL));
    Express[80].push_back(searchForNode(COMMA,ISTERMINAL));
    Express[80].push_back(searchForNode(ActParamList,NOTERMINAL));
    Express[81].push_back(searchForNode(RelExp,NOTERMINAL));
    Express[81].push_back(searchForNode(Exp,NOTERMINAL));
    Express[81].push_back(searchForNode(OtherRelE,NOTERMINAL));
    Express[82].push_back(searchForNode(OtherRelE,NOTERMINAL));
    Express[82].push_back(searchForNode(CmpOp,NOTERMINAL));
    Express[82].push_back(searchForNode(Exp,NOTERMINAL));
    Express[83].push_back(searchForNode(Exp,NOTERMINAL));
    Express[83].push_back(searchForNode(Term,NOTERMINAL));
    Express[83].push_back(searchForNode(OtherTerm,NOTERMINAL));
    Express[84].push_back(searchForNode(OtherTerm,NOTERMINAL));
    Express[84].push_back(searchForNode(LAMBDA,ISTERMINAL));
    Express[85].push_back(searchForNode(OtherTerm,NOTERMINAL));
    Express[85].push_back(searchForNode(AddOp,NOTERMINAL));
    Express[85].push_back(searchForNode(Exp,NOTERMINAL));
    Express[86].push_back(searchForNode(Term,NOTERMINAL));
    Express[86].push_back(searchForNode(Factor,NOTERMINAL));
    Express[86].push_back(searchForNode(OtherFactor,NOTERMINAL));
    Express[87].push_back(searchForNode(OtherFactor,NOTERMINAL));
    Express[87].push_back(searchForNode(LAMBDA,ISTERMINAL));
    Express[88].push_back(searchForNode(OtherFactor,NOTERMINAL));
    Express[88].push_back(searchForNode(MultOp,NOTERMINAL));
    Express[88].push_back(searchForNode(Term,NOTERMINAL));
    Express[89].push_back(searchForNode(Factor,NOTERMINAL));
    Express[89].push_back(searchForNode(LPAREN,ISTERMINAL));
    Express[89].push_back(searchForNode(Exp,NOTERMINAL));
    Express[89].push_back(searchForNode(RPAREN,ISTERMINAL));
    Express[90].push_back(searchForNode(Factor,NOTERMINAL));
    Express[90].push_back(searchForNode(INTC,ISTERMINAL));
    Express[91].push_back(searchForNode(Factor,NOTERMINAL));
    Express[91].push_back(searchForNode(Variable,NOTERMINAL));
    Express[92].push_back(searchForNode(Variable,NOTERMINAL));
    Express[92].push_back(searchForNode(ID,ISTERMINAL));
    Express[92].push_back(searchForNode(VariMore,NOTERMINAL));
    Express[93].push_back(searchForNode(VariMore,NOTERMINAL));
    Express[93].push_back(searchForNode(LAMBDA,ISTERMINAL));
    Express[94].push_back(searchForNode(VariMore,NOTERMINAL));
    Express[94].push_back(searchForNode(LMIDPAREN,ISTERMINAL));
    Express[94].push_back(searchForNode(Exp,NOTERMINAL));
    Express[94].push_back(searchForNode(RMIDPAREN,ISTERMINAL));
    Express[95].push_back(searchForNode(VariMore,NOTERMINAL));
    Express[95].push_back(searchForNode(DOT,ISTERMINAL));
    Express[95].push_back(searchForNode(FieldVar,NOTERMINAL));
    Express[96].push_back(searchForNode(FieldVar,NOTERMINAL));
    Express[96].push_back(searchForNode(ID,ISTERMINAL));
    Express[96].push_back(searchForNode(FieldVarMore,NOTERMINAL));
    Express[97].push_back(searchForNode(FieldVarMore,NOTERMINAL));
    Express[97].push_back(searchForNode(LAMBDA,ISTERMINAL));
    Express[98].push_back(searchForNode(FieldVarMore,NOTERMINAL));
    Express[98].push_back(searchForNode(LMIDPAREN,ISTERMINAL));
    Express[98].push_back(searchForNode(Exp,NOTERMINAL));
    Express[98].push_back(searchForNode(RMIDPAREN,ISTERMINAL));
    Express[99].push_back(searchForNode(CmpOp,NOTERMINAL));
    Express[99].push_back(searchForNode(LT,ISTERMINAL));
    Express[100].push_back(searchForNode(CmpOp,NOTERMINAL));
    Express[100].push_back(searchForNode(EQ,ISTERMINAL));
    Express[101].push_back(searchForNode(AddOp,NOTERMINAL));
    Express[101].push_back(searchForNode(PLUS,ISTERMINAL));
    Express[102].push_back(searchForNode(AddOp,NOTERMINAL));
    Express[102].push_back(searchForNode(MINUS,ISTERMINAL));
    Express[103].push_back(searchForNode(MultOp,NOTERMINAL));
    Express[103].push_back(searchForNode(TIMES,ISTERMINAL));
    Express[104].push_back(searchForNode(MultOp,NOTERMINAL));
    Express[104].push_back(searchForNode(OVER,ISTERMINAL));
#ifndef NoCharC
    Express[105].push_back(searchForNode(Factor,NOTERMINAL));
    Express[105].push_back(searchForNode(CHARC,ISTERMINAL));
#endif
}

ExpNode* searchForNode(int lt, int flag)
{
    if(flag == ISTERMINAL)
    {
        if(ExpNodes[lt].NTflag == ISTERMINAL)
        {
            return &ExpNodes[lt];
        }
        else
        {
            exit(1);
        }
    }
    else if(ExpNodes[int(LexType::UNDERANGE)+1+lt].NTflag == NOTERMINAL)
    {
        return &ExpNodes[int(LexType::UNDERANGE)+1+lt];
    }
    else
    {
        exit(2);
    }
}
